package com.sloth.bear.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sloth.bear.dto.entity.User;
import com.sloth.bear.dto.request.LoginRequest;
import com.sloth.bear.dto.request.UserCreateRequest;
import com.sloth.bear.dto.vo.LoginVo;
import com.sloth.bear.dto.vo.UserVo;
import com.sloth.bear.mapper.UserMapper;
import com.sloth.bear.service.UserService;
import com.sloth.bear.util.AssertUtils;
import com.sloth.bear.util.BaseHelper;
import com.sloth.bear.util.JwtUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final BCryptPasswordEncoder passwordEncoder;
    private final JwtUtils jwtUtils;

    @Override
    public void createUser(UserCreateRequest request) {
        long count = count(Wrappers.<User>lambdaQuery().eq(User::getUsername, request.getUsername()));
        AssertUtils.isTrue(count == 0, "用户名已存在");

        User user = BaseHelper.r2t(request, User.class);
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        if (!StringUtils.hasText(user.getNickname())) {
            user.setNickname(user.getUsername());
        }

        boolean result = save(user);
        AssertUtils.isTrue(result, "用户创建失败");
    }

    @Override
    public LoginVo login(LoginRequest request) {
        User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, request.getUsername()));
        AssertUtils.notNull(user, "用户名或密码错误");

        // 验证密码
        boolean passwordMatches = passwordEncoder.matches(request.getPassword(), user.getPassword());
        AssertUtils.isTrue(passwordMatches, "用户名或密码错误");

        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        updateById(user);

        // 生成JWT token
        String token = jwtUtils.generateToken(user.getId(), user.getUsername());

        // 构造返回结果
        LoginVo loginVo = BaseHelper.r2t(user, LoginVo.class);
        loginVo.setToken(token);
        return loginVo;
    }
}